#include <LitStdAfx.h>
#include <LitPhysicsDebug.h>
#include <LitSceneManager.h>
#include <LitPhysicsWorld.h>
#include <LitCore.h>

namespace Lit
{
	namespace Physics
	{
		Debugger::Object::Object(  Ogre::SceneManager * mgr, Ogre::SceneNode * parent )
		{
			scene = mgr;
			manual = scene->createManualObject();
			node = parent->createChildSceneNode();
			node->attachObject( manual );
		}
		Debugger::Object::~Object( )
		{
			if( scene && node->getAttachedObjectIterator().hasMoreElements() )
			{
				node->detachAllObjects();
				scene->destroyManualObject(manual);
				scene->destroySceneNode( node );
				scene = NULL;
			}
		}

		void Debugger::perPolygon( void * userData, int vert_cnt, const float * faceArray, int fid )
		{
			Ogre::Vector3 p0, p1;
			int i= vert_cnt - 1;
			Body * body = (Body*)userData;
			Matrix mat( body->getMatrix() );
			p0 = Ogre::Vector3( faceArray[(i*3) + 0], faceArray[(i*3) + 1], faceArray[(i*3) + 2] );
			for (i=0;i<vert_cnt;i++)
			{
					p1 = Ogre::Vector3( faceArray[(i*3) + 0], faceArray[(i*3) + 1], faceArray[(i*3) + 2] );
					mMap.back()->manual->position( p0 );
					mMap.back()->manual->position( p1 );
	
					p0 = p1;
			}
			//mMap.back()->node->setPosition( /*mat2.getTrans()+body->getShape()->initialMatrix().getPosition()*/ );
		}
		Debugger::Debugger(Ogre::SceneManager * mgr, World* world) : mSceneMgr(mgr), mWorld(world){
			setVisible( false );
		}
		Debugger::~Debugger(){
			destroyNodes( );
		}

		void Debugger::setVisible( bool state ){ 
			mVisible = state; 
			for( auto i=mMap.begin(); i!=mMap.end(); i++ ) 
			{ (*i)->node->setVisible( state ); (*i)->manual->setVisible( state ); }
		}
		bool Debugger::isVisible() const{ return mVisible; }

		void Debugger::destroyNodes( )
		{
			for( auto i=mMap.begin(); i!=mMap.end(); i++ )
				if( *i ) delete *i, *i = NULL;
			mMap.clear();
		}
		void Debugger::rebuildLines( )
		{
			if( !mVisible ) return;
			destroyNodes();
			BodyPtr body = mWorld->getFirstBody();
			while( body )
			{
				Object * obj = new Object( mSceneMgr, mSceneMgr->getRootSceneNode() );
				mMap.push_back( obj );
				obj->manual->begin("RedTransparent", Ogre::RenderOperation::OT_LINE_LIST );
				body->forEachPolygon( boost::bind( &Debugger::perPolygon, this, _1, _2, _3, _4 ) );
				obj->manual->end();
				body=mWorld->getNextBody(*body);
			}
		}
	};

};